package com.stu.reflection.test_declared;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class TestDeclared {
  public static void main(String[] args) throws Exception {
    testNo();
    System.out.println("---------------");
    testYes();
    /*测试结果：
      属性：2:[a1, f1]
      方法：11:[t1, m1, wait, wait, wait, equals, toString, hashCode, getClass, notify, notifyAll]
      构造：1:[public com.stu.reflection.test_declared.Pojo()]
      ---------------
      属性：4:[a1, a2, a3, a4]
      方法：4:[t2, t1, t3, t4]
      构造：4:[Pojo(int,int), protected Pojo(int), private Pojo(int,int,int), public Pojo()]
      // 这里太长了，故将 com.stu.reflection.test_declared. 省略
    */
    // 从测试结果发现：没有Declared的方法只能读取到本类及其所有超类的公有结构，有Declared的方法只能读取到本类的所有（无论公有私有保护默认）结构
    // 结论：无Declared：读取继承链公有；有Declared：读取本类全部
  }

  // 测试没有 Delared 的情况
  static void testNo() throws Exception {
    Class<?> clazz = Class.forName("com.stu.reflection.test_declared.Pojo");

    Field[] fields = clazz.getFields();
    Object[] fieldNames = Arrays.stream(fields)
                            .map(full -> full.getName())
                            .toArray();
    System.out.println("属性："+fields.length+":"+Arrays.toString(fieldNames));

    Method[] methods = clazz.getMethods();
    Object[] methodNames = Arrays.stream(methods)
                            .map(full -> full.getName())
                            .toArray();
    System.out.println("方法："+methods.length+":"+Arrays.toString(methodNames));

    Constructor<?>[] constructors = clazz.getConstructors();
    System.out.println("构造："+constructors.length+":"+Arrays.toString(constructors));
  }

  // 测试有 Delared 的情况
  static void testYes() throws Exception {
    Class<?> clazz = Class.forName("com.stu.reflection.test_declared.Pojo");

    Field[] fields = clazz.getDeclaredFields();
    Object[] fieldNames = Arrays.stream(fields)
                            .map(full -> full.getName())
                            .toArray();
    System.out.println("属性："+fields.length+":"+Arrays.toString(fieldNames));

    Method[] methods = clazz.getDeclaredMethods();
    Object[] methodNames = Arrays.stream(methods)
                            .map(full -> full.getName())
                            .toArray();
    System.out.println("方法："+methods.length+":"+Arrays.toString(methodNames));

    Constructor<?>[] constructors = clazz.getDeclaredConstructors();
    System.out.println("构造："+constructors.length+":"+Arrays.toString(constructors));
  }
}
